`timescale 1ns / 1ps
//////////////////////////////////////////////////////////////////////////////////
// Module: Top                                                                  //
// Author: Zhiyuan Lin                                                          //
// Date: 4/28/2014                                                              //
//////////////////////////////////////////////////////////////////////////////////
module Top(
		output 	reg	[7:0]	img,
		output					HS,VS,Gain, Shutdown, Speaker,
		output			[7:0] LED,		
		input						clk, K_CLK, Data
		);
	  
	wire 				pixel_clk, blank, clk_1KHz, clk_800Hz, clk_700Hz, clk_5Hz;
	wire	[7:0]		C1, C2, C3, C4, C5;
	wire	[10:0]	hcounter,vcounter;
	wire	[2:0] 	R, G;
	wire	[1:0]		B;
	
	wire Play_END;
	wire Game_OVER;
	
	wire S_Song1_1, S_Song2_2, S_Song3_3;
	reg  S_Pause_SPACE, S_Start_0, S_Turbo_4,
		  B_Restart_R, B_QuitPause_ESC, B_QuitOver_Q, 
		  B_Enter_ENTER, B_EnterGame_M,
		  B_Btn1_Z, B_Btn2_X, B_Btn3_C, B_Btn4_V;	
	
	reg	[2:0]		state = 3'b000;

	
	assign	C5[7:5]=R;
	assign	C5[4:2]=G;
	assign	C5[1:0]=B;
	
//////////////////////////KEYBOARD//////////////////////////////////////
	
    reg Start, Pause, Turbo;
    reg [2:0] Select;
    
    assign S_Song1_1 = Select[0];
    assign S_Song2_2 = Select[1];  	 
	 assign S_Song3_3 = Select[2];

    reg [7:0] Data_Curr, Data_Past; 
    reg [3:0] b; 
    reg FLAG; 
	
always @(negedge K_CLK) //Activating at negative edge of clock from keyboard 
  begin 
  case(b) 
	 1:; //first bit 
	 2:Data_Curr[0] <= Data; 
	 3:Data_Curr[1] <= Data; 
	 4:Data_Curr[2] <= Data; 
	 5:Data_Curr[3] <= Data; 
	 6:Data_Curr[4] <= Data; 
	 7:Data_Curr[5] <= Data; 
	 8:Data_Curr[6] <= Data; 
	 9:Data_Curr[7] <= Data; 
	 10:FLAG<=1; //Parity bit 
	 11:FLAG<=0; //Ending bit 								
  endcase 
  if(b <= 10) 		
	  b <= b + 1; 
  else 
	  b <= 1;			
end 

always@(posedge FLAG)
  begin			
  if (Data_Past == 8'hF0) 
    begin		
      case (Data_Curr)
	   8'h45: Start 	 <= 0;	
	   8'h29: Pause    <= 0;
	   8'h25: Turbo    <= 0;
		
		
		8'h2D: B_Restart_R   	<= 0;
		8'h1A: B_Btn1_Z 			<= 0;
		8'h22: B_Btn2_X 			<= 0;
		8'h21: B_Btn3_C 			<= 0;
		8'h2A: B_Btn4_V 			<= 0;
      8'h76: B_QuitPause_ESC 	<= 0;
      8'h15: B_QuitOver_Q 		<= 0;
      8'h5A: B_Enter_ENTER 	<= 0;
		8'h3A: B_EnterGame_M    <= 0;
		
	   endcase															
	   Data_Past <= Data_Curr;
  end
  else 
    begin
		
		if (Data_Curr == 8'h16) //1 for Song1
		  begin
		  Select <= 001;							
		  Data_Past <= Data_Curr;
		end
		
		else if (Data_Curr == 8'h1E) //2 for Song2
		  begin							
		  Select <= 010;							
		  Data_Past <= Data_Curr;					
		end	
		
		else if (Data_Curr == 8'h26) //3 for Song3
		  begin
          Select <= 100;		     											
			 Data_Past <= Data_Curr;
		end
			
		else if (Data_Curr == 8'h45) //S for Start
		  begin							
		    Start <= 1;							
			 Data_Past <= Data_Curr;
		end
		
		else if (Data_Curr == 8'h29) //SPACE for Pause
		  begin	
        Pause <= 1;		   
		  Data_Past <= Data_Curr;
		end
		
		else if (Data_Curr == 8'h25) //4 for Turbo
		  begin							
		  Turbo <= 1;
		  Data_Past <= Data_Curr;
		end
		
		else if (Data_Curr == 8'h2D) //R for Restart
		  begin							
		  B_Restart_R <= 1;
		  Data_Past <= Data_Curr;
		end
		
		else if (Data_Curr == 8'h1A) //Z for Btn1
		  begin							
		  B_Btn1_Z <= 1;
		  Data_Past <= Data_Curr;
		end
		
		else if (Data_Curr == 8'h22) //X for Btn2
		  begin							
		  B_Btn2_X <= 1;
		  Data_Past <= Data_Curr;
		end
		
		else if (Data_Curr == 8'h21) //C for Btn3
		  begin							
		  B_Btn3_C <= 1;
		  Data_Past <= Data_Curr;
		end
		
		else if (Data_Curr == 8'h2A) //V for Btn4
		  begin							
		  B_Btn4_V <= 1;
		  Data_Past <= Data_Curr;
		end
		
		else if (Data_Curr == 8'h76) //ESC for PauseState Quit
		  begin							
		  B_QuitPause_ESC <= 1;
		  Data_Past <= Data_Curr;
		end
		
		else if (Data_Curr == 8'h15) //Q for OverState Quit
		  begin							
		  B_QuitOver_Q <= 1;
		  Data_Past <= Data_Curr;
		end
		
		else if (Data_Curr == 8'h5A) //ENTER for StartState Enter
		  begin							
		  B_Enter_ENTER <= 1;
		  Data_Past <= Data_Curr;
		end
		
		else if (Data_Curr == 8'h3A) //M for Game Enter
		  begin							
		  B_EnterGame_M <= 1;
		  Data_Past <= Data_Curr;
		end
	
		else
		  begin 							
		  Data_Past <= Data_Curr;
		end			
  end
end		

always@(posedge Start)
	begin	
	  S_Start_0 <= S_Start_0 + 1;
	end
	
always@(posedge Pause)
	begin			
	  S_Pause_SPACE <= S_Pause_SPACE + 1;
	end
	
always@(posedge Turbo)
	begin			
	  S_Turbo_4 <= S_Turbo_4 + 1;
	end	
	
//////////////////////END KEYBOARD/////////////////////////////////////
	
/*	AUDIO_KEYBOARD K1	(K_CLK, Data, S_Pause_SPACE, S_Start_0, 
	                   S_Song1_1, S_Song2_2, S_Song3_3, S_Turbo_4,
							 B_Restart_R, B_QuitPause_ESC, B_QuitOver_Q, B_Enter_ENTER, B_EnterGame_M,
							 B_Btn1_Z, B_Btn2_X, B_Btn3_C, B_Btn4_V);	*/
						 
	
	vga_controller_640_60 VC1(pixel_clk,HS,VS,hcounter,vcounter,blank);
	clock_div	CD0(pixel_clk, clk_1KHz, clk_5Hz, clk_800Hz, clk_700Hz, clk);
	Frame1		F1(C1, hcounter, vcounter, clk , clk_5Hz, blank	);
	Frame2		F2(C2, hcounter, vcounter, clk , clk_5Hz, blank	);
	Frame3		F3(C3, hcounter, vcounter, clk , clk_5Hz, blank /*S_Pause_SPACE, RESTART, QUIT*/);
	Frame4		F4(C4, hcounter, vcounter,	clk , clk_5Hz, blank, /*LEVEL_SELECT, SONG_SELECT*/S_Song1_1, S_Song2_2, S_Song3_3, S_Turbo_4);
	
	
	AUDIO_TOPV2 A1(clk, Gain, Shutdown, Speaker_PLAY, LED, Play_END, Game_OVER,
	                  R, G, B, , , 
							S_Pause_SPACE, S_Start_0, B_Restart_R,
							S_Turbo_4, S_Song1_1, S_Song2_2, S_Song3_3,
							B_Btn1_Z, B_Btn2_X, B_Btn3_C, B_Btn4_V);
							
//	state=000		press enter key to start, jump to state 011
// state=001		game over, press enter key to replay, jump to state 011
//	state=010	   pause state, press R key to replay, jump to state 011 OR press esc to jump to state 000
//	state=011		song selection, press 1 for song No.1, .....4 for hard, 5 for easy, enter to jump to state 100
//	state=100		gaming, Play_END or GAME_OVER == 1, jump to state 001, press esc, jump to state 010	
//////////////////////////STATE MACHINE//////////////////////////////////////

assign Speaker = (state == 3'b100)? Speaker_PLAY : 1'b0;
					
	always@(posedge clk_1KHz)
		begin
			if (state == 3'b000)
				begin					
					if (B_Enter_ENTER == 1)
						begin
							state <= 3'b011;
						end	
				end
				
			else if (state == 3'b001)
				begin
					if (B_QuitOver_Q == 1)
						begin
							state <= 3'b011;
						end	
				end
				
			else if (state == 3'b010)
				begin
					if (B_QuitPause_ESC == 1)
						begin
							state <= 3'b000;
						end
               else if (S_Pause_SPACE == 0)
                  begin
						   state <= 3'b100;
                  end						
				end
				
			else if (state == 3'b011)
				begin
//					if ((((S_Song1_1 == 1) && (S_Song2_2 == 0) && (S_Song3_3 == 0)) ||
//					     ((S_Song1_1 == 0) && (S_Song2_2 == 1) && (S_Song3_3 == 0)) ||
//						  ((S_Song1_1 == 0) && (S_Song2_2 == 0) && (S_Song3_3 == 1))) && (B_EnterGame_M == 1))
//               if(((S_Song1_1 == 1) || (S_Song2_2 == 1) || (S_Song3_3 == 1)) && (B_EnterGame_M == 1))
               if (B_EnterGame_M == 1)
						begin
							state <= 3'b100;
						end
				end
				
			else if (state == 3'b100)
				begin
					if (S_Pause_SPACE == 1)
						begin
							state <= 3'b010;
						end
               else if ((Play_END == 1) || (Game_OVER == 1))
/*                else if (Play_END == 1)*/
						begin
							state <= 3'b001;
						end
				end
			else 
				state <= 3'b000;
		end	
	
	always@(posedge clk)
		begin
			if (blank==0)	
				begin
					case(state)
						3'b000:	img<=C1;
						3'b001:	img<=C2;
						3'b010:	img<=C3;
						3'b011:	img<=C4;
						3'b100:	img<=C5;
					default: img<=8'bz;
					endcase
					
				end
			else
				begin
					img<=8'bz;
				end
		end
		
endmodule
